#include "mainwindow.h"
#include "ui_mainwindow.h"



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);


//    elibraryparser_author elA;
//    QList<int> ArS;
//    ArS = elA.GetAuthorList();

//    connName = "conn1";
    lblStatus = new QLabel("  ");
    statusBar()->addWidget(lblStatus);
   // stopL = new stopList("/home/replay/test_sw.txt");
    stopL = new stopList("test_sw.txt");
    QButtonGroup *gbDist = new QButtonGroup(  );
    QButtonGroup *gbWeight = new QButtonGroup( );
    gbDist->addButton( ui->rbTF );
    gbDist->addButton( ui->rbTFIDF );
    gbWeight->addButton( ui->rbEucl );
    gbWeight->addButton( ui->rbCheb );
    gbWeight->addButton( ui->rbManh );
    ui->rbTF->setChecked(true);
    ui->rbEucl->setChecked(true);

    QObject::connect(ui->btnAnalysis, SIGNAL(clicked()), this, SLOT(dataAnalys()));
    QObject::connect(ui->btnAuthor, SIGNAL(clicked()), this, SLOT(byAuthor()));
    QObject::connect(ui->btnCreate, SIGNAL(clicked()), this, SLOT(dbTableCreate()));
    QObject::connect(ui->btnExec, SIGNAL(clicked()), this, SLOT(dbExec()));
    QObject::connect(ui->btnInsert, SIGNAL(clicked()), this, SLOT(dbInsert()));
    QObject::connect(ui->btnJournal, SIGNAL(clicked()), this, SLOT(byJournal()));
    QObject::connect(ui->btnOpen, SIGNAL(clicked()), this, SLOT(dbOpen()));
    QObject::connect(ui->btnShow, SIGNAL(clicked()), this, SLOT(dbShow()));
    QObject::connect(ui->btnDist, SIGNAL(clicked()), this, SLOT(calcDist()));
    QObject::connect(ui->btnJaccard, SIGNAL(clicked()), this, SLOT(calcJaccard()));
    QObject::connect(ui->btnLeven, SIGNAL(clicked()), this, SLOT(calcLeven()));
    QObject::connect(ui->btnShingle, SIGNAL(clicked()), this, SLOT(calcShingle()));
    QObject::connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addText()));
    QObject::connect(ui->btnSearch, SIGNAL(clicked()), this, SLOT(sameSearch()));
    QObject::connect(ui->listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(docSelect()));
    QObject::connect(ui->btnLoad, SIGNAL(clicked()), this, SLOT(pubLoad()));
    QObject::connect(ui->btnGetID, SIGNAL(clicked()), this, SLOT(getID()));
    QObject::connect(ui->btnClear, SIGNAL(clicked()), this, SLOT(lstClear()));

    showURL = new QAction("Show/Hide URL", this);
    showFullText = new QAction("Show/Hide FullText", this);
    showArticleName = new QAction("Show/Hide ArticleName", this);
    showJournalInfo = new QAction("Show/Hide JournalInfo", this);
    showJournalName = new QAction("Show/Hide JournalName", this);
  //  showURL = new QAction("Show/Hide URL", this);
   // showURL = new QAction("Show/Hide URL", this);
    //showURL = new QAction("Show/Hide URL", this);
    connect(showURL, SIGNAL(triggered()), this, SLOT(showU()));
    connect(showFullText, SIGNAL(triggered()), this, SLOT(showFT()));
    connect(showArticleName, SIGNAL(triggered()), this, SLOT(showAN()));
    connect(showJournalInfo, SIGNAL(triggered()), this, SLOT(showJI()));
    connect(showJournalName, SIGNAL(triggered()), this, SLOT(showJN()));
}


MainWindow::~MainWindow()
{
    delete ui;
//   closeConnection(*db, connName);
}

void MainWindow::showU()
{
    if (ui->tableView->isColumnHidden(6))
    {
        ui->tableView->showColumn(6);
    }
    else
    {
        ui->tableView->hideColumn(6);
    }
}

void MainWindow::showFT()
{
    if (ui->tableView->isColumnHidden(5))
    {
        ui->tableView->showColumn(5);
    }
    else
    {
        ui->tableView->hideColumn(5);
    }
}

void MainWindow::showAN()
{
    if (ui->tableView->isColumnHidden(3))
    {
        ui->tableView->showColumn(3);
    }
    else
    {
        ui->tableView->hideColumn(3);
    }
}

void MainWindow::showJI()
{
    if (ui->tableView->isColumnHidden(2))
    {
        ui->tableView->showColumn(2);
    }
    else
    {
        ui->tableView->hideColumn(2);
    }
}

void MainWindow::showJN()
{
    if (ui->tableView->isColumnHidden(1))
    {
        ui->tableView->showColumn(1);
    }
    else
    {
        ui->tableView->hideColumn(1);
    }
}

void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(showURL);
    menu.addAction(showFullText);
    menu.addAction(showArticleName);
    menu.addAction(showJournalInfo);
    menu.addAction(showJournalName);
    menu.exec(event->globalPos());
}

//static void closeConnection(QSqlDatabase _db, QString _connName)
//{
////    if (_db.isOpen())
////    {
////        _db.close();
////    }
////    QSqlDatabase::removeDatabase("ololo");

//                                QSqlDatabase _db = QSqlDatabase::database(_connName, false);
//                                if (_db.isOpen())
//                                    _db.close();
//                            QSqlDatabase::removeDatabase(_connName);
//}

//static bool createConnction(QSqlDatabase _db, QString _dbName)
//{
//    _db = QSqlDatabase::addDatabase("QSQLITE");
//    //_db.database("conn1");
//    _db.setDatabaseName(_dbName);
//    if (!_db.open())
//    {
//        qDebug() << "ololoshibka: " << _db.lastError();
//        return false;
//    }
//    return true;
//}

//static void createTable(QString tableName)
//{
//    QSqlQuery query;
//    QString str = "CREATE TABLE " + tableName + "( "
//                      "AuthorNames VARCHAR(200), "
//                      "JournalName VARCHAR(200), "
//                      "JournalInfo VARCHAR(50), "
//                      "ArticleName VARCHAR(250), "
//                      "Annotation VARCHAR(400), "
//                      "FullText VARCHAR(500), "
//                      "ArticleURL VARCHAR(100)"
//                      ");";
//    if (!query.exec(str))
//    {
//        qDebug() << "bedaaaaCreate!!" << query.lastError();
//    }
//}



void MainWindow::dbExec()
{
    QSqlQuery query;
    if (!query.exec(ui->tbExec->text()))
    {
        qDebug() << "bedaaaaExec!!" << query.lastError();
    }
    dbShow();
}

void MainWindow::dbInsert()
{
    lblStatus->setText("Please Wait... Downloading");
    eLibraryParser_Journal elP;
    QList<ArticleStruct> ArS;
    ArS = elP.GetArticleList(ui->tbInsert->text().toInt());
    QSqlQuery query;
    QString strF =
            "INSERT INTO " + ui->tbTableName->text() +
            " (AuthorNames, JournalName, JournalInfo, ArticleName, Annotation, FullText, ArticleURL)"
            "VALUES('%1', '%2', '%3', '%4', '%5', '%6', '%7' )";

    foreach (ArticleStruct ArtStrct, ArS)
    {
        QString ANames = " ";
        QString Ann = " ";
        foreach (QString _Ann, ArtStrct.Annotations)
        {
            Ann += _Ann;
        }
       if (!Ann.trimmed().isEmpty())
       {
        foreach (QString Auth, ArtStrct.AuthorNames)
        {
            ANames += Auth + ", ";
        }
        Annotations.push_back(ArtStrct.Annotations[0]);
        QString str = strF.arg(ANames)
                  .arg(ArtStrct.JournalName)
                  .arg(ArtStrct.JournalInfo)
                  .arg(ArtStrct.ArticleName)
                  .arg(ArtStrct.Annotations[0])
                  .arg(ArtStrct.FullText)
                  .arg(ArtStrct.ArticleUrl.toString());
        if (!query.exec(str))
        {
            qDebug() << "bedaaaaInsert!!" << query.lastError();
        }
       }
    }
    qDebug() << "ololo zaparsilos";
    lblStatus->setText("Downloading Done");
    dbShow();
}

void MainWindow::dbOpen()
{
    QString dbName = ui->tbName->text();
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(dbName);
    if (!db.open())
    {
        qDebug() << "bedaaaaOpen!!: " << db.lastError();
    }
}

void MainWindow::dbShow()
{
    Annotations.clear();
    Authors.clear();
    Journals.clear();
    model = new QSqlTableModel;
    model->setTable(ui->tbTableName->text());
    model->setEditStrategy(QSqlTableModel::OnFieldChange);
    model->select();
    ui->tableView->setModel(model);
   // lblStatus->setText(QString::number(model->rowCount()));
//    ui->tableView->hideColumn(6);
//    ui->tableView->hideColumn(5);
//    ui->tableView->hideColumn(3);
//    ui->tableView->hideColumn(2);

    for (int i = 0; i < model->rowCount(); i++)
    {
        foreach (QString str, model->record(i).value(0).toString().trimmed().split(",",QString::SkipEmptyParts))
        {
            Authors.push_back(str.trimmed());
        }
        Journals.push_back(model->record(i).value(1).toString());
        Annotations.push_back(model->record(i).value(4).toString());
    }

    Authors.removeDuplicates();
    Authors.sort();
    Journals.removeDuplicates();
    Journals.sort();
    ui->cbAuthor->clear();;
    ui->cbJournal->clear();;
    ui->cbAuthor->addItems(Authors);
    ui->cbJournal->addItems(Journals);
    ui->cbAvtor->clear();
    ui->cbAvtor->addItem("all");
    ui->cbAvtor->addItems(Authors);
}

void MainWindow::dbTableCreate()
{
    QString tableName = ui->tbTableName->text();
    QSqlQuery query;
    QString str = "CREATE TABLE " + tableName + "( "
                      "AuthorNames VARCHAR(200), "
                      "JournalName VARCHAR(200), "
                      "JournalInfo VARCHAR(50), "
                      "ArticleName VARCHAR(250), "
                      "Annotation VARCHAR(400), "
                      "FullText VARCHAR(500), "
                      "ArticleURL VARCHAR(100)"
                      ");";
    if (!query.exec(str))
    {
        qDebug() << "bedaaaaCreate!!" << query.lastError();
    }
}

void MainWindow::byAuthor()
{
    model = new QSqlTableModel;
    model->setTable(ui->tbTableName->text());
    model->setFilter("AuthorNames like '%" + ui->cbAuthor->currentText() + "%'");
    model->select();
    ui->tableView->setModel(model);
}

void MainWindow::byJournal()
{
    model = new QSqlTableModel;
    model->setTable(ui->tbTableName->text());
    model->setFilter("JournalName like '%" + ui->cbJournal->currentText() + "%'");
    model->select();
    ui->tableView->setModel(model);
}

void MainWindow::dataAnalys()
{
    ui->listWidget->clear();
    dStruct.clear();
    dStructPure.clear();
    addTexts(Annotations);
    ui->tabWidget->setCurrentIndex(1);
}

void MainWindow::fillTable(QList<vect> _qlv)
{
    QList<vect> qlv = _qlv;
    ui->tableWidget->setColumnCount(qlv.count());
    ui->tableWidget->setRowCount(qlv.at(0).count());
    int i = 0;
    foreach (vect vct, qlv)
    {
        int j = 0;
        foreach (float fl, vct)
        {
            QTableWidgetItem *newItem = new QTableWidgetItem(QString::number(fl));
            ui->tableWidget->setItem(i,j,newItem);
            j++;
        }
        i++;
    }
}

void MainWindow::calcDist()
{
    QString strDist;
    QString strWeight;
    if (ui->rbTF->isChecked()) {strWeight = ui->rbTF->objectName();}
    if (ui->rbTFIDF->isChecked()) {strWeight = ui->rbTFIDF->objectName();}
    if (ui->rbEucl->isChecked()) {strDist = ui->rbEucl->objectName();}
    if (ui->rbManh->isChecked()) {strDist = ui->rbManh->objectName();}
    if (ui->rbCheb->isChecked()) {strDist = ui->rbCheb->objectName();}
    tfcalc tfcl(dStructPure);
    fillTable(tfcl.getDist(strDist,strWeight));
}

void MainWindow::calcJaccard()
{
    tfcalc tfcl(dStructPure);
    fillTable(tfcl.calculateJaccard());
}

void MainWindow::calcLeven()
{
    tfcalc tfcl(dStructPure);
    fillTable(tfcl.calculateLeven(dStructPure));
}

void MainWindow::calcShingle()
{
    int shLength = ui->tbShingleLength->text().toInt();
    int hashLength = ui->tbHashLength->text().toInt();
    tfcalc tfcl(dStructPure);
    fillTable(tfcl.calculateShingle(dStructPure, shLength, hashLength));
}

void MainWindow::addText()
{
    DocStruct dstr;
    foreach (QString str, ui->teAddText->toPlainText().split(" ",QString::SkipEmptyParts))
    {
        dstr.Text.append(str);
    }
    DocStruct dstrPure;
    dStruct.append(dstr);
    foreach (QString str, ui->teAddText->toPlainText().replace(QRegExp("[^\\w]+"), " ").split(" ",QString::SkipEmptyParts))
    {
        if (!stopL->isStop(str.toLower()))
        {
            dstrPure.Text.append(str.toLower());
        }
    }
    dStructPure.append(dstrPure);
    ui->listWidget->addItem("doc" + QString::number(ui->listWidget->count() + 1));
    ui->teText->setText(ui->teAddText->toPlainText());
    ui->teAddText->setText("");
    QString strPure;
    foreach (QString s, dstrPure.Text)
    {
        strPure += s + " ";
    }
    ui->tePureText->setText(strPure);
    QString numStr;
    ui->groupBox_4->setTitle("Source Text: " + numStr.setNum(dstr.Text.count()) + " words");
    ui->groupBox_5->setTitle("Pure Text: " + numStr.setNum(dstrPure.Text.count()) + " words");
    ui->teAddText->setFocus();
}

void MainWindow::docSelect()
{
    DocStruct dStr;
    QString str;
    dStr = dStruct[ui->listWidget->currentRow()];
    foreach (QString s, dStr.Text)
    {
        str += s + " ";
    }
    ui->teText->clear();
    ui->teText->setPlainText(str);

    DocStruct dStrPure;
    QString strPure;
    dStrPure = dStructPure[ui->listWidget->currentRow()];
    foreach (QString s, dStrPure.Text)
    {
        strPure += s + " ";
    }
    ui->tePureText->clear();
    ui->tePureText->setPlainText(strPure);
    QString numStr;
    ui->groupBox_4->setTitle("Source Text: " + numStr.setNum(dStr.Text.count()) + " words");
    ui->groupBox_5->setTitle("Pure Text: " + numStr.setNum(dStrPure.Text.count()) + " words");
}

void MainWindow::addTexts(QStringList sl)
{
    DocStruct dstr;
    DocStruct dstrPure;
    foreach (QString str,  sl) //ui->textEdit_2->toPlainText().split(" ",QString::SkipEmptyParts))
    {
        dstr.Text.clear();
        QStringList qsl = str.split(" ",QString::SkipEmptyParts);
        foreach(QString str1, qsl)
        {
            dstr.Text.append(str1);
        }
        dStruct.append(dstr);
        dstrPure.Text.clear();
        foreach(QString str1, str.replace(QRegExp("[^\\w]+"), " ").split(" ",QString::SkipEmptyParts))
        {
            if (!stopL->isStop(str1.toLower()))
            {
                dstrPure.Text.append(str1.toLower());
            }
        }
        dStructPure.append(dstrPure);
        ui->listWidget->addItem("doc" + QString::number(ui->listWidget->count() + 1));
    }
}

void MainWindow::sameSearch()
{
    if (db.isOpen())
    {
        dStructAutoA.clear();
        analAnnotations.clear();
        ui->plainTextEdit->clear();
        model = new QSqlTableModel;
        model->setTable(ui->tbTableName->text());
        if (ui->cbAvtor->currentText() != "all")
        {
            model->setFilter("AuthorNames like '%" + ui->cbAvtor->currentText() + "%'");
        }
        model->select();
        //lblStatus->setText(QString::number());

        lblStatus->setText("Annotations Loading...");
        for (int i = 0; i < model->rowCount(); i++)
        {
            analAnnotations.push_back(model->record(i).value(4).toString());
        }
        ui->progressBar->setValue(10);
        DocStruct dstrAutoA;
        lblStatus->setText("Text Clearing...");
        foreach (QString str,  analAnnotations)
        {
            dstrAutoA.Text.clear();
            foreach(QString str1, str.replace(QRegExp("[^\\w]+"), " ").split(" ",QString::SkipEmptyParts))
            {
                if (!stopL->isStop(str1.toLower()))
                {
                    dstrAutoA.Text.append(str1.toLower());
                }
            }
            dStructAutoA.append(dstrAutoA);
        }
        ui->progressBar->setValue(30);
        tfcalc tfcl(dStructAutoA);
        lblStatus->setText("Distance Calculating...");
        QList<vect> qlvDist = tfcl.getDist("rbEucl","rbTFIDF");
        QList<vect> qlvJaccard = tfcl.calculateJaccard();
        QList<vect> qlvLeven = tfcl.calculateLeven(dStructAutoA);
        QList<vect> qlvShingle = tfcl.calculateShingle(dStructAutoA,2,15);
        ui->progressBar->setValue(50);
        //ui->plainTextEdit->appendPlainText("Author: " + ui->cbAvtor->currentText() + "\n");
        QString numStrI;
        QString numStrJ;
        QString numStrD;
        int cnt = 0;
        lblStatus->setText("Data Adding...");
        if (qlvDist.length() > 1)
        {
            for (int i = 0; i < qlvDist.length(); i++)
            {
                for (int j = 0; j < qlvDist.length(); j++)
                {
                    if (i < j)
                    {
                        if (
                                (ui->rbCompDist->isChecked() && ui->tbCompare->text().toFloat() > qlvDist[i][j])  ||
                                (ui->rbCompJaccard->isChecked() && ui->tbCompare->text().toFloat() < qlvJaccard[i][j])  ||
                                (ui->rbCompLeven->isChecked() && ui->tbCompare->text().toFloat() > qlvLeven[i][j])  ||
                                (ui->rbCompShingle->isChecked() && ui->tbCompare->text().toFloat() < qlvShingle[i][j])
                            )
                        {
                            ++cnt;
                            ui->plainTextEdit->appendPlainText("#######################______"+ QString::number(cnt) +"______######################### \n");
                            ui->plainTextEdit->appendPlainText("Docs" + numStrI.setNum(i + 1) + " & "
                                                               + numStrJ.setNum(j + 1) + "\n Dist: "
                                                               + numStrD.setNum(qlvDist[i][j]) );
                            ui->plainTextEdit->appendPlainText(" Jaccard: " + numStrD.setNum(qlvJaccard[i][j]));
                            ui->plainTextEdit->appendPlainText(" Levenshtein: " + numStrD.setNum(qlvLeven[i][j]));
                            ui->plainTextEdit->appendPlainText(" Shingle: " + numStrD.setNum(qlvShingle[i][j]) + "\n");
                            //ui->plainTextEdit->appendPlainText("\n");
                            ui->plainTextEdit->appendPlainText("Authors: ");
                            ui->plainTextEdit->appendPlainText(model->record(i).value(0).toString() + "\n");
                            ui->plainTextEdit->appendPlainText("Caption: ");
                            ui->plainTextEdit->appendPlainText(model->record(i).value(3).toString() + "\n");
                            ui->plainTextEdit->appendPlainText(model->record(i).value(4).toString() + "\n");
                            ui->plainTextEdit->appendPlainText("Authors: ");
                            ui->plainTextEdit->appendPlainText(model->record(j).value(0).toString() + "\n");
                            ui->plainTextEdit->appendPlainText("Caption: ");
                            ui->plainTextEdit->appendPlainText(model->record(j).value(3).toString() + "\n");
                            ui->plainTextEdit->appendPlainText(model->record(j).value(4).toString() + "\n");
                            ui->progressBar->setValue(50 + i);
                        }
                        else
                        {

                        }
                    }
                }
            }
            if (ui->plainTextEdit->toPlainText().trimmed() == "Author: " + ui->cbAvtor->currentText())
            {
                ui->plainTextEdit->appendPlainText("There is no data with such limits");
            }
        }
        else
        {
            ui->plainTextEdit->appendPlainText("Author has only one documet");
        }
        ui->progressBar->setValue(100);
        lblStatus->setText("Done");
     //   */
    }
    else
    {
        lblStatus->setText("Please open DB");
    }

}

void MainWindow::getID()
{
    ui->lstID->clear();
    int pubLim = ui->tbPubLim->text().toInt();
    elibraryparser_author elA;
    QList<int> listID;
    listID = elA.GetAuthorList(pubLim);
    foreach (int i, listID)
    {
        ui->lstID->addItem(QString::number(i));
    }
}

void MainWindow::pubLoad()
{
    int pubLim = ui->tbPubLim->text().toInt();
    elibraryparser_author elA;
    QList<int> listID;
    listID = elA.GetAuthorList(pubLim);
    lblStatus->setText("Downloading Start");
    int cnt = 0;
    foreach (int i, listID)
    {
        lblStatus->setText(QString(("Current: " + QString::number(cnt) + " Total: " + QString::number(elA.GetAuthorCount()))));
        ui->lstID->addItem(QString::number(i));
        eLibraryParser_Journal elP;
        QList<ArticleStruct> ArS;
        ArS = elP.GetArticleList(i);
        QSqlQuery query;
        QString strF =
                "INSERT INTO " + ui->tbTableName->text() +
                " (AuthorNames, JournalName, JournalInfo, ArticleName, Annotation, FullText, ArticleURL)"
                "VALUES('%1', '%2', '%3', '%4', '%5', '%6', '%7' )";

        foreach (ArticleStruct ArtStrct, ArS)
        {
            QString ANames = " ";
            QString Ann = " ";
            foreach (QString _Ann, ArtStrct.Annotations)
            {
                Ann += _Ann;
            }

           if ((Ann[0] > 'z') && (!Ann.trimmed().isEmpty()))
           {
            foreach (QString Auth, ArtStrct.AuthorNames)
            {
                ANames += Auth + ", ";
            }
            Annotations.push_back(ArtStrct.Annotations[0]);
            QString str = strF.arg(ANames)
                      .arg(ArtStrct.JournalName)
                      .arg(ArtStrct.JournalInfo)
                      .arg(ArtStrct.ArticleName)
                      .arg(ArtStrct.Annotations[0])
                      .arg(ArtStrct.FullText)
                      .arg(ArtStrct.ArticleUrl.toString());
            if (!query.exec(str))
            {
                qDebug() << "bedaaaaInsert!!" << query.lastError();
            }
           }
        }
        ++cnt;
    }
    lblStatus->setText("Downloading Done");
}

void MainWindow::lstClear()
{
    dStruct.clear();
    dStructPure.clear();
    ui->listWidget->clear();
    ui->teText->clear();
    ui->tePureText->clear();
    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(0);
    ui->tableWidget->setRowCount(0);
}
